<?php
/**
 * Core_Record_Order
 * 
 * @author naspeh
 * @version $Id: Order.php 661 2008-06-16 10:38:02Z naspeh $
 */
class Core_Record_Order
{
    /**
     * Разделитель выражений сортировки в url 
     *
     */
    const ORDER_SEPARATOR = ':';
    /**
     * Пробельный символ в url для выражения сортировки
     *
     */
    const SPACE_SIMBOL = '-';
    /**
     * Обект списка
     *
     * @var Core_Record
     */
    protected $_record;
    /**
     * Список выражений сортировки
     *
     * @var unknown_type
     */
    protected $_orders = array();
    /**
     * Конструктор
     *
     * @param Core_Record $record
     */
    public function __construct(Core_Record $record)
    {
        $this->_record = $record;
    }
    /**
     * Возвращает обьект списка
     *
     * @return Core_Record
     */
    public function getRecord()
    {
        return $this->_record;
    }
    /**
     * Возвращает массив полей, по которым производится сортировка.
     *
     * @return array
     */
    public function getFromQuery() {
        $request = Core_Controller_Front::getInstance()->getRequest();
        $this->remove();
        if (null !== ($source = $request->getParam('order'))) {
            $source = str_replace(self::SPACE_SIMBOL, ' ', $source);
            $source = split(self::ORDER_SEPARATOR, $source);
            foreach ($source as $order) {
                $this->isValid($order);
            }
        }
        return $this->_orders;
    }
    /**
     * Проверяет валидность поля для сортировки
     *
     * @param string $order
     * @return string
     */
    public function isValid($order)
    {
        
        $chain = new Zend_Validate_Regex('/[\w]/');
        if ($chain->isValid($order)) {
            if (false == ($field = $this->isDesc($order))) {
                $field = $order;
            }
            if ($this->getRecord()->getSource()->isValidField($field) && $this->getRecord()->getFields($field)->getOrder()) {
                $this->_orders[$field] = $order;
                return $field;                
            }
        }
        throw new Core_Exception('badColumnInOrder# Неправильное поле в списке сортировки: ' . $order, 404);
    }
    /**
     * Добавляет выражение сортировки
     *
     * @param string $field
     * @param boolean $desc
     * @return Core_Record_Order
     */
    public function add($field, $desc = false)
    {
        if ($this->getRecord()->getSource()->isValidField($field))
        {
            if ($desc) {
            	$this->_orders[$field] =  $field . ' desc';
            } else {
            	$this->_orders[$field] =  $field;
            }
        }
        return $this;
    }
    /**
     * Возвращает выражения(е) сортировки
     *
     * @param string $field
     * @return array|string|null
     */
    public function get($field = null)
    {
        $this->getFromQuery();
        if (!isset($field)) {
        	return $this->_orders;
        }
        
        if (!isset($this->_orders[$field])) {
        	return null;
        }
        return $this->_orders[$field];
    }
    /**
     * Возвращает строку, определяющую следующую сортировку
     * для вставки в url
     *
     * @param string $field
     * @return string
     */
    public function next($field)
    {
        if (null !== ($order = $this->get($field))) {
            if ($this->isDesc($order)) {
            	$this->remove($field);
            } else {
                $this->add($field, true);
            }
            
        } else {
        	$this->add($field);
        }
        return $this->getUrl();
    }
    /**
     * Проверяет является ли выражение сортировки типа desc
     *
     * @param string $order
     * @return string|false
     */
    public function isDesc($order)
    {
        if (preg_match('/^(\w*) desc$/', $order, $matches)) {
            return $matches[1];
        } else {
        	return false;
        }
    }
    /**
     * Возвращает стоку из выражения сортировки для вставки в url
     *
     * @return string
     */
    public function getUrl()
    {
        $request = Core_Controller_Front::getInstance()->getRequest();
        $url = $request->getRequestUri();
        $order = implode(self::ORDER_SEPARATOR, $this->_orders);
        if (null!==($orderUrl = $request->getParam('order'))) {
            $url = preg_replace('/\/order\/' . $orderUrl . '/', '', $url);
        }
        if('' != $order) {
            $order = str_replace(' ', self::SPACE_SIMBOL, $order);
            $url = rtrim($url, '/\\');
            $url .= '/order/' . $order;
        }
        return $url;    
    }
    /**
     * Удаляет выражение сортировки
     *
     * @param string $field
     * @return Core_Record_Order
     */
    public function remove($field = null)
    {
        if (!isset($field)) {
            $this->_orders = array();
        }
        
        if (isset($this->_orders[$field])) {
            unset($this->_orders[$field]);
        }
        return $this;
    }
}
